package cn.gx.kevin.common.utils;

import java.io.File;
import java.io.InputStream;
import java.util.*;
import java.util.Map.Entry;

import cn.gx.kevin.common.bootenv.SpringContextUtil;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.env.Environment;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

/**
 * @ClassName: SysConfigParams
 * @Description: TODO
 * @author kevin.huang
 * @date 2016年4月23日 下午1:46:31
 */
public class SysConfigParams {

    private static final Logger logger = LoggerFactory.getLogger(SysConfigParams.class);

    private static Environment environment = null;
    public static boolean isDefaultClassPath = true;
    public static String configHome;
    public static String jdbcFile = "jdbc.properties";
    public static Resource JdbcResouce;
    public static String lang = "zh";
    public static Map<String, Set<String>> exceptValidationMap = new HashMap();
    public static Map<String, Set<String>> oepnApiMap = new HashMap();
    public static String webHttpContext;
    private static Boolean devModel = null;
    private static String entryKey = null;
    private static String cookieKey = null;
    private static Map<String, String> configMap = new HashMap();
    private static String[] excludeDownLoadList = null;

    public SysConfigParams() {
    }

    public static String configInfo() {
        return "configHome=" + configHome + ";jdbcFile=" + jdbcFile;
    }

    public static Environment getEnvironment(){
        if(environment != null){
            return environment;
        }
        environment = SpringContextUtil.getEnvironment();
        return environment;
    }


    public static boolean isOpenApi(String controller, String cmd) {
        Set<String> cmdSet1 = (Set)oepnApiMap.get("*");
        if (cmdSet1 != null && cmdSet1.contains(cmd)) {
            return true;
        } else {
            Set<String> cmdSet = (Set)oepnApiMap.get(controller);
            if (cmdSet == null) {
                return false;
            } else {
                return cmdSet.contains("*") || cmdSet.contains(cmd);
            }
        }
    }

    public static void setOpenApi(String controller, String cmd) {
        Set<String> cmdSet = (Set)oepnApiMap.get(controller);
        if (cmdSet == null) {
            cmdSet = new HashSet();
            oepnApiMap.put(controller, cmdSet);
        }
        ((Set)cmdSet).add(cmd);
    }

    public static boolean canAccess(String controller, String cmd) {
        Set<String> cmdSet1 = (Set)exceptValidationMap.get("*");
        if (cmdSet1 != null && cmdSet1.contains(cmd)) {
            return true;
        } else {
            Set<String> cmdSet = (Set)exceptValidationMap.get(controller);
            if (cmdSet == null) {
                return false;
            } else {
                return cmdSet.contains("*") || cmdSet.contains(cmd);
            }
        }
    }

    public static Set<String> getNoValidController() {
        Set<String> set = new HashSet();
        Iterator var1 = exceptValidationMap.entrySet().iterator();
        while(var1.hasNext()) {
            Entry<String, Set<String>> entry = (Entry)var1.next();
            if (((Set)entry.getValue()).contains("*")) {
                set.add(entry.getKey());
            }
        }
        return set;
    }

    public static void setExceptValidation(String controller, String cmd) {
        Set<String> cmdSet = (Set)exceptValidationMap.get(controller);
        if (cmdSet == null) {
            cmdSet = new HashSet();
            exceptValidationMap.put(controller, cmdSet);
        }

        ((Set)cmdSet).add(cmd);
    }

    public static String getEntryKey() {
        if (entryKey == null) {
            entryKey = getConfig("entryKey");
        }
        return entryKey;
    }

    public static String getCookieKey() {
        if (cookieKey == null) {
            cookieKey = getConfig("cookieKey");
        }
        return cookieKey;
    }

    public static boolean isDevModel() {
        if (devModel != null) {
            return devModel;
        } else {
            String dev = getConfig("isDevModel");
            devModel = dev == null || dev.equals("true");
            return devModel;
        }
    }
    public static String getUploadRootDir(Environment env){
        environment = env;
        return getUploadRootDir();
    }
    public static String getUploadRootDir(){
        if(environment == null){
            getEnvironment();
        }
        String uploadDir = environment.getProperty("upload.dir");
        if(uploadDir == null || uploadDir.equals("appdir")){
            uploadDir = System.getProperty("user.dir") + File.separator + "upload";
        }
        File dir = new File(uploadDir);
        if(!dir.exists()){
            dir.mkdirs();
        }
        return uploadDir + File.separator;
    }

    public static String getUploadImagesDir(){
        String uploadDir = SysConfigParams.getUploadRootDir() + "images" + File.separator;
        File tmpDir = new File(uploadDir);
        if (!tmpDir.exists()) {
            tmpDir.mkdirs();
        }
        return uploadDir;
    }

    public static String getUploadFilesDir(){
        String uploadDir = SysConfigParams.getUploadRootDir() + "files" + File.separator;
        File tmpDir = new File(uploadDir);
        if (!tmpDir.exists()) {
            tmpDir.mkdirs();
        }
        return uploadDir;
    }

    public static String getUploadXlsDir(){
        String uploadDir = SysConfigParams.getUploadRootDir() + "xls" + File.separator;
        File tmpDir = new File(uploadDir);
        if (!tmpDir.exists()) {
            tmpDir.mkdirs();
        }
        return uploadDir;
    }
    public static String getUploadTmplsDir(){
        String uploadDir = SysConfigParams.getUploadRootDir() + "tmpls" + File.separator;
        File tmpDir = new File(uploadDir);
        if (!tmpDir.exists()) {
            tmpDir.mkdirs();
        }
        return uploadDir;
    }

    public static String getConfig(String key) {
       Object objVal = configMap.get(key);
       if(objVal != null){
           return String.valueOf(objVal);
       }
        getEnvironment();
        if(environment != null){
            return  environment.getProperty(key);
        }else{
            logger.error("getConfig environment is null ");
        }
        return null;
    }

    public static void setConfig(String key, String value) {
        if (!configMap.containsKey(key)) {
            configMap.put(key, value);
        }
    }

    public static void initDownLoadExclude() {
        String downloadexclude = (String)configMap.get("downloadexclude");
        if (StringUtils.isNotEmpty(downloadexclude)) {
            String[] tmp = downloadexclude.split(";");
            int size = 0;
            String[] var3 = tmp;
            int var4 = tmp.length;

            int var5;
            for(var5 = 0; var5 < var4; ++var5) {
                String s = var3[var5];
                if (!"".equals(s)) {
                    ++size;
                }
            }
            if (size > 0) {
                excludeDownLoadList = new String[size];
                int i = 0;
                String[] var9 = tmp;
                var5 = tmp.length;

                for(int var10 = 0; var10 < var5; ++var10) {
                    String s = var9[var10];
                    if (!"".equals(s)) {
                        excludeDownLoadList[i] = webHttpContext + "/" + s;
                        ++i;
                    }
                }
            }
        }

    }

    public static boolean isDownLoadExclude(String url) {
        if (excludeDownLoadList == null) {
            return false;
        } else {
            boolean isExclude = false;
            if (url.indexOf(".") > 0) {
                String[] var2 = excludeDownLoadList;
                int var3 = var2.length;
                for(int var4 = 0; var4 < var3; ++var4) {
                    String prex = var2[var4];
                    if (url.indexOf(prex) == 0) {
                        isExclude = true;
                        break;
                    }
                }
            }
            return isExclude;
        }
    }

    public static void initExcludeValidCfg() throws Throwable {
        PathMatchingResourcePatternResolver resoler = new PathMatchingResourcePatternResolver();
        Resource resource = resoler.getResource("classpath:/exclude-validation.xml");
        if(resource.exists()){
            logger.info("initExcludeValidCfg "+ resource.toString());
            InputStream xmlFileStream = resource.getInputStream();
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document doc = builder.parse(xmlFileStream);
            NodeList list = doc.getElementsByTagName("controller");
            for(int i = 0; i < list.getLength(); ++i) {
                Element node = (Element)list.item(i);
                String c = node.getAttribute("name");
                String access = node.getAttribute("openapi");
                if (StringUtils.isNotEmpty(access)) {
                    setOpenApi(c, "*");
                }
                NodeList cmdlist = node.getElementsByTagName("cmd");
                if (cmdlist.getLength() > 0) {
                    int k = 0;
                    for(int len = cmdlist.getLength(); k < len; ++k) {
                        Element n = (Element)cmdlist.item(k);
                        String cmd = n.getFirstChild().getNodeValue();
                        String cmdAccess = node.getAttribute("openapi");
                        if (StringUtils.isNotEmpty(cmdAccess)) {
                            setOpenApi(c, cmd);
                        }
                        setExceptValidation(c, cmd);
                    }
                }
            }
        }
    }
}
